<template>
	<div class="" v-viewer="{url: 'data-src' }">
		<el-upload ref="shsUpload" action="#" :on-remove="handleRemove" :before-upload="beforeUpload"
			:on-exceed="handledExceed" :show-file-list="false" name="shsuploadfile" :file-list="imageList"
			:disabled="disable" :multiple="true" :limit="maxUploadCount" :on-error="handleError"
			:on-success="handleSuccess" :on-progress="handleProgress"
			accept=".jpg,.jpeg,.png,.gif,.webp,.mp4,.avi,.mov,JPG,JPEG,PNG,GIF,WEBP,MP4,AVI,MOV"
			v-loading="UploadLoading" element-loading-text="服务器处理中,请耐心等待">
			<el-button slot="trigger" size="small" :disabled="disable" type="primary">
				选择文件
			</el-button>
			<el-button style="margin-left: 20px;" size="small" :disabled="disable && fileList.length==0" type="success"
				@click="submitUpload">上传到服务器</el-button>
			<div slot="tip" class="el-upload__tip">
				支持图片和视频格式
			</div>
		</el-upload>
		<div class="stateImagesBox">
			<template v-for="item,index in fileList">
				<div class="stateImages" :key="`images${item.uid}`">
					<video v-if="item.type.includes('video')" class="item" controls preload="metadata">
						<source :src="tempUrl(item)" type="video/mp4">
					</video>
					<img v-else :src="tempUrl(item)" :data-src="tempUrl(item)" class="item" style="object-fit:cover;" />
					<span @click="handledCancel(item.uid)" class="upload-cancel cursorPointer">X</span>
				</div>
			</template>
		</div>
		<div class="marginT5 " style="font-size: 12px;" v-if="percent && percent!=100">
			<span>进度{{percent}}%</span>
			<span v-if="isddxc" class="marginL10 marginT5 cursorPointer shs-cancle" @click="handledCancle">X</span>
		</div>
	</div>
</template>

<script>
	import axios from 'axios'
	import {
		upload,
		uploadVideo
	} from '@/api/upload'
	import {
		imageNowIP
	} from "@/utils/config"
	import {
		deepClone
	} from "@/utils/base"
	import {
		uniqueE
	} from "@/utils/common"
	export default {
		name: 'Upload',
		model: {
			prop: 'value',
			event: 'input',
		},
		props: {
			value: {
				type: Array,
				required: true,
				default: () => []
			},
			disable: {
				type: Boolean,
				default: false,
			},
			maxUploadCount: {
				type: Number | String,
				default: 2,
			}
		},
		data() {
			const videoLimitSizeMb = 450;
			const imageLimitSizeMb = 2;
			const videoLimitSize = videoLimitSizeMb * 1024 * 1024;
			const imageLimitSize = imageLimitSizeMb * 1024 * 1024;
			return {
				UploadLoading: false, //加载框
				percent: 0,
				videoLimitSizeMb,
				imageLimitSizeMb,
				videoLimitSize, //视频大小限制
				imageLimitSize, //图片大小限制
				isddxc: false, //是否支持断点续传 未实现
				// 上传地址
				imageNowIP: imageNowIP,
				doUpload: imageNowIP + '/upload_file_image',
				uploadListReady: [],
				fileList: [],
				imagesArray: ["jpg", "jpeg", "png", "gif", "webp", "mp4", "avi", "mov", "JPG", "JPEG", "PNG", "GIF",
					"WEBP", "MP4", "AVI", "MOV"
				],

			};
		},
		computed: {
			imageList() {
				return this.value;
			},

		},
		watch: {},
		methods: {
			uniqueE,
			tempUrl(file) {
				return URL.createObjectURL(file)
			},
			/**取消上传*/
			handledCancel(uid) {
				this.fileList = this.fileList.filter(function(item, index, arr) {
					return item.uid != uid
				}, this)
			},
			//超出限制文件个数
			handledExceed(files, fileList) {
				try {
					let diff = this.maxUploadCount - this.imageList.length
					this.$message.error(`还可以上传${diff}个图像! [${this.imageList.length}/${this.maxUploadCount}]`);
				} catch (error) {
					//TODO handle the exception
				}
			},
			// 提交上传，控制并发数量
			async submitUpload() {
				if (this.fileList.length === 0) {
					this.$message.warning('请先选择文件');
					return;
				}
				// 创建一个数组来存储要上传的文件块
				let uploadQueue = [...this.fileList];

				while (uploadQueue.length > 0) {
					// 每次从队列中取出3个文件进行上传
					this.UploadLoading = true;
					let uploadBatch = uploadQueue.splice(0, 3);
					// 等待这一批文件上传完成
					await this.uploadFiles(uploadBatch);
					this.UploadLoading = false;
				}
				// 所有文件上传完成后，清空fileList
				this.fileList = [];
			},
			async uploadFiles(files) {
				let uploadPromises = files.map(file => {
					let formData = new FormData();
					formData.append('shsuploadfile', file);
					let baseUrl = file.type.includes('image') ? '/upload_file_image' :
						'/upload_file_video_hls';
					let url = this.imageNowIP + baseUrl;
					return axios({
						url,
						method: 'POST',
						data: formData,
						onUploadProgress: (progressEvent) => {
							let percent = Math.floor((progressEvent.loaded / progressEvent.total) *
								100);
							this.percent = percent
							this.$set(file, 'percentage', percent); // 更新上传进度

						}
					}).then(res => {
						if (res.data.code === 200) {
							res.data.uniqueID = this.uniqueE(8, 16);
							this.imageList.push(res.data);
							this.triggerChange(this.imageList);
						} else {
							this.$message.error('文件上传失败：' + res.data.message);
							file.status = 'fail';
						}
					}).catch(err => {
						this.$message.error('文件上传请求失败');
						file.status = 'fail';
					});
				});
				// 等待这一批文件的所有请求都完成
				await Promise.all(uploadPromises);
			},
			// 上传前
			beforeUpload(file) {
				if (this.imagesArray.indexOf(file.type.split("/")[1]) == -1) {
					this.$message.error("文件格式错误")
					return false;
				}
				let diff = this.maxUploadCount - this.imageList.length - this.fileList.length
				if (file.type.includes("image")) {
					const limitFileSize = file.size < this.imageLimitSize;
					if (!limitFileSize) {
						this.$message.error(`图片大小不能超过 ${this.imageLimitSizeMb}MB!`);
					} else {
						if (diff) {
							this.fileList.push(file)
						} else {
							this.handledExceed()
						}

					}
				} else if (file.type.includes("video")) {
					const limitFileSize = file.size < this.videoLimitSize;
					if (!limitFileSize) {
						this.$message.error(`视频大小不能超过 ${this.videoLimitSizeMb}MB!`);
					} else {
						if (diff) {
							this.fileList.push(file)
						} else {
							this.handledExceed()
						}
					}
				} else {
					this.$message.error("文件格式错误");
				}
				return false;
			},
			// 手动删除文件钩子
			handleRemove(_file, fileList) {
				// this.processFileList(fileList);
			},
			// 自定义处理filelist
			processFileList(fileList) {
				// this.triggerChange(fileList);
			},
			triggerChange(fileList) {
				this.$emit('input', fileList);
			},
			handleSuccess(res, file, fileList) {

			},
			handleError(err) {
				try {
					this.$message.error("文件上传错误" + (err.message || err.msg));
				} catch (e) {}
			},
			handleProgress(event, file, fileList) {
				this.percent = event.percent
			},
			/**
			 * 中断上传
			 */
			handledCancle() {},
			// 自定义上传方法
			async mystyleUpload(option) {
				return false;
				let _this = this;
				let formData = new FormData();
				formData.append('shsuploadfile', option.file);

				let baseUrl = option.file.type.includes("image") ?
					"/upload_file_image" :
					"/upload_file_video_hls";
				let url = this.imageNowIP + baseUrl;

				try {
					axios({
						url,
						method: 'POST',
						data: formData,
						onUploadProgress: (progressEvent) => {
							let percent = Math.floor((progressEvent.loaded / progressEvent.total) *
								100);
							if (option && typeof option.onProgress === 'function') {
								option.onProgress({
									percent
								});
							}
						}
					}).then(res => {
						if (res.data.code === 200) {
							try {
								res.data.uniqueID = uniqueE(8, 16);
								let value = [...this.imageList, res.data];
								_this.triggerChange(value);
							} catch (e) {
								console.error("处理成功响应时发生错误", e);
								option.onError(e);
							}
						} else {
							option.onError(res.data);
						}
					}).catch(err => {
						option.onError(err);
					})
				} catch (error) {
					// 捕获axios请求过程中的任何错误
					console.error("上传文件时发生错误", error);
					option.onError(error);
				}
			},

		},
	};
</script>
<style scoped>
	.shs-cancle {
		background-color: red;
		width: 20vw;
		height: 20px;
		line-height: 20px;
		display: inline-block;
		text-align: center;
	}

	.stateImagesBox {
		width: 100%;
		position: relative;
		display: flex;
		justify-content: flex-start;
		align-items: center;
		flex-wrap: wrap;
		flex-direction: row;
		margin-top: 20px;
	}

	.stateImagesBox .stateImages {
		width: calc(49.8%);
		height: 148px;
		padding: 1px;
		box-sizing: border-box;
		position: relative;
	}

	.stateImages .item {
		width: 100%;
		height: 100%;
		margin: 0;
		padding: 0;
	}

	.upload-cancel {
		float: right;
		display: inline-block;
		position: absolute;
		text-align: center;
		box-sizing: border-box;
		width: 25px;
		height: 25px;
		line-height: 25px;
		top: 0;
		right: -5px;
		border-radius: 50%;
		z-index: 2222;
		background: rgba(139, 139, 139, 1.0);
		color: #fff;
	}
</style>